package com.quanyan.club.service.impl;

import com.quanyan.club.entity.db.TbClubExperienceHistory;
import com.quanyan.club.entity.db.TbExperienceParameter;
import com.quanyan.club.entity.db.TbLevel;
import com.quanyan.club.entity.vo.resp.RespClubLevelResult;
import com.quanyan.club.entity.vo.resp.RespExperienceParameter;
import com.quanyan.club.mapper.TbClubExperienceHistoryMapper;
import com.quanyan.club.mapper.TbExperienceParameterMapper;
import com.quanyan.club.mapper.TbLevelMapper;
import com.quanyan.club.service.ClubXpLevelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Administrator on 2016/7/22.
 */
@Service("clubXpLevelService")
public class ClubXpLevelServiceImpl implements ClubXpLevelService {
    private static final Logger logger = LoggerFactory.getLogger(ClubXpLevelServiceImpl.class);

    private final ReentrantLock lock = new ReentrantLock();

    @Autowired
    private TbExperienceParameterMapper experienceParameterMapper;
    @Autowired
    private TbClubExperienceHistoryMapper clubExperienceHistoryMapper;
    @Autowired
    private TbLevelMapper levelMapper;

    @Override
    public RespExperienceParameter getExperienceParameter(String expName) {
        TbExperienceParameter experienceParameter = experienceParameterMapper.selectByPrimaryExpName(expName);
        RespExperienceParameter respExperienceParameter = new RespExperienceParameter();
        if (experienceParameter != null) {
            respExperienceParameter.setId(experienceParameter.getId());
            respExperienceParameter.setExperience(experienceParameter.getExperience());
            respExperienceParameter.setExpName(experienceParameter.getExpName());
            respExperienceParameter.setExpNumber(experienceParameter.getExpNumber());
            respExperienceParameter.setType(experienceParameter.getType());
        }

        return respExperienceParameter;
    }

    @Override
    public boolean isExistClubExperienceHistory(String expName, Integer clubId) {
        Integer count = clubExperienceHistoryMapper.countByExpName(expName, clubId);
        return count > 0 ? true : false;
    }

    @Override
    public void insertClubExperienceHistory(TbClubExperienceHistory clubExpHistory) {
        clubExperienceHistoryMapper.insertClubExpHistory(clubExpHistory);
    }

    @Override
    public Integer countByCurDate(String expName, Integer clubId) {
        return clubExperienceHistoryMapper.countByCurDate(expName, clubId);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public void modifyClubExperience(Integer clubId, Integer exp) {
        lock.lock();
        try {
            int updateResult = updateClubLevel(clubId, exp);
            if (updateResult <= 0) { //更新失败,重试一次
                updateClubLevel(clubId, exp);
            }
        }finally {
            lock.unlock();
        }
    }

    private int updateClubLevel(Integer clubId, Integer exp) {
        TbLevel level = levelMapper.selectByCommonId(clubId);
        int sourceLevel = level.getLevel().intValue();
        int updateResult = 0;
        if (level != null) {
            RespClubLevelResult clubLevelResult = levelMapper.selectClubLevelXp(level.getXp() + exp);
            if (clubLevelResult != null) {
                level.setNextLevelXp(clubLevelResult.getNextLevelXp());
                level.setLevel(clubLevelResult.getLevel());
                level.setXp(level.getXp() + exp);
                updateResult = levelMapper.updateLevel(level);
                if (updateResult > 0 &&  sourceLevel != clubLevelResult.getLevel().intValue()) {
                    levelMapper.updateClubLevel(clubLevelResult.getLevel(), clubId);
                }
            }
        }else{
            RespClubLevelResult levelResult = levelMapper.selectClubLevelXp(exp);
            TbLevel tbLevel = new TbLevel();
            tbLevel.setType((byte)2);
            if (levelResult != null) {
                tbLevel.setNextLevelXp(levelResult.getNextLevelXp());
                tbLevel.setLevel(levelResult.getLevel());
            }else{
                tbLevel.setNextLevelXp(0);
                tbLevel.setLevel(0);
            }
            tbLevel.setXp(exp);
            tbLevel.setCommonId(clubId);
            levelMapper.insertSelective(tbLevel);
            updateResult = 1;
        }
        return updateResult;
    }
}
